#pragma once

#include <memory>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <atomic>
#include <stdexcept>
#include "../logger.hpp"

// 连接池配置
struct ConnectionPoolConfig {
    size_t initial_size = 5;      // 初始连接数
    size_t max_size = 20;         // 最大连接数
    size_t max_idle_time = 60;    // 最大空闲时间(秒)
    size_t connection_timeout = 3; // 连接超时时间(秒)
};

// 连接池基类
template<typename ConnectionType>
class ConnectionPool {
public:
    explicit ConnectionPool(const ConnectionPoolConfig& config) 
        : config_(config)
        , current_size_(0) {
    }

    virtual ~ConnectionPool() {
        // 清理所有连接
        std::lock_guard<std::mutex> lock(mutex_);
        while (!idle_connections_.empty()) {
            auto conn = idle_connections_.front();
            idle_connections_.pop();
            close_connection(conn.get());
        }
    }

    // 获取连接
    std::shared_ptr<ConnectionType> get_connection() {
        std::unique_lock<std::mutex> lock(mutex_);
        
        // 等待可用连接
        bool has_resource = cv_.wait_for(lock, 
            std::chrono::seconds(config_.connection_timeout),
            [this]() { 
                return !idle_connections_.empty() || 
                       current_size_ < config_.max_size; 
            });

        if (!has_resource) {
            throw std::runtime_error("Connection timeout");
        }

        std::shared_ptr<ConnectionType> conn;

        if (idle_connections_.empty()) {
            // 创建新连接
            conn = create_connection();
            if (conn) {
                current_size_++;
            }
        } else {
            // 获取空闲连接
            conn = idle_connections_.front();
            idle_connections_.pop();

            // 验证连接是否有效
            if (!validate_connection(conn.get())) {
                close_connection(conn.get());
                conn = create_connection();
                // 打印日志，创建了新连接 (加入打印函数的名字)
                Logger::info("{} create new connection from pool", __func__);
                if (!conn) {
                    current_size_--;
                    throw std::runtime_error("Failed to create connection");
                }
            }
        }

        // 打印日志，获取了连接
        Logger::info("get connection from pool");

        // 包装连接，添加自动归还功能
        return std::shared_ptr<ConnectionType>(conn.get(), 
            [this, conn](ConnectionType*) {
                this->return_connection(conn);
            });
    }

    // 获取当前连接数
    size_t get_current_size() const {
        return current_size_;
    }

    // 获取空闲连接数
    size_t get_idle_size() const {
        std::lock_guard<std::mutex> lock(mutex_);
        return idle_connections_.size();
    }

    // 初始化连接池
    void initialize() {
        std::lock_guard<std::mutex> lock(mutex_);
        for (size_t i = 0; i < config_.initial_size; ++i) {
            // 应该转换成子类的create_connection，否则会报错
            auto raw_conn = create_connection();
            if (raw_conn) {
                idle_connections_.push(std::shared_ptr<ConnectionType>(raw_conn));
                current_size_++;
            }
        }
    }

protected:
    // 创建新连接（由子类实现）
    virtual std::shared_ptr<ConnectionType> create_connection() = 0;
    
    // 验证连接是否有效（由子类实现）
    virtual bool validate_connection(ConnectionType* conn) = 0;
    
    // 关闭连接（默认实现为空）
    virtual void close_connection(ConnectionType* conn) {}

private:
    // 归还连接到连接池
    void return_connection(std::shared_ptr<ConnectionType> conn) {
        std::lock_guard<std::mutex> lock(mutex_);
        if (validate_connection(conn.get())) {
            idle_connections_.push(conn);
            cv_.notify_one();
        } else {
            close_connection(conn.get());
            current_size_--;
        }
    }

    ConnectionPoolConfig config_;
    std::queue<std::shared_ptr<ConnectionType>> idle_connections_;
    mutable std::mutex mutex_;
    std::condition_variable cv_;
    std::atomic<size_t> current_size_;
};